
package instrumentation;

import java.io.Serializable;
import java.util.List;
public class DataUse implements Serializable {

	private static final long serialVersionUID = -372367168640928525L;
	private final int id;
	private static int idGenerator = 1;

	private final Data data;
	private  DataDef defInBlock;
	public DataUse( Data data, List<DataDef> blockDefs) {
		id = idGenerator++;
		Value v1=data;
	try{
		for(int i=blockDefs.size()-1;i>=0;i--){
			DataDef def=blockDefs.get(i);
			Value tmp=def.getData()!=null?def.getData():def.getValue();
			if(tmp.toString().equals(v1.toString())) {
					v1 =def.getValue();
					if(v1==null) break;
					if(v1 instanceof Virtualinvoke){
						if(((Virtualinvoke) v1).getD().isField() || ((Virtualinvoke) v1).getD().isParam())
								this.defInBlock = new DataDef( (Data)data, v1);//def;
						else{
							List<Value> lstArgs=((Virtualinvoke) v1).getArgs();
							if(lstArgs.size()!=0 && !(lstArgs.get(0) instanceof ConstantString)){
								Data arg=(Data)lstArgs.get(0);
								if(arg.isField()||arg.isParam())
									this.defInBlock = new DataDef( (Data)data, v1);
							}
							else
							v1=((Virtualinvoke) v1).getD();
						}
						}
						else if(v1 instanceof ValueArray){
							if(((ValueArray) v1).getD()!=null){
								if(((ValueArray) v1).getD().isField() || ((ValueArray) v1).getD().isParam())
									this.defInBlock = new DataDef( (Data)data, v1);//def;
							}
							else{
								Data arg=(Data)((ValueArray) v1).getArgs();
									if(arg.isField()||arg.isParam())
										this.defInBlock = new DataDef( (Data)data, (Value)arg);
								}
//								else
//									v1 =((ValueArray) v1).getD();
						}else this.defInBlock = new DataDef( (Data)data, v1);//def;
			}
		}
	} catch (Exception e) {
		System.err.println("Error during DataUse: " + e);
	//	System.exit(1);
	}

		this.data = data;
	}

	public int getId() {
		return id;
	}

	public Data getData() {
		return data;
	}
	public DataDef getDefInBlock() {
		return this.defInBlock;
	}


	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
//		sb.append(this.cName);
//		sb.append(".");
	//	sb.append(data.toString());
		sb.append(this.defInBlock==null?" " : this.defInBlock );
//		sb.append(this.getData());
		
		
		return sb.toString();
	}
}
